package com.self.cloudmall.wms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.self.cloudmall.common.enumm.PurDetailStateEnum;
import com.self.cloudmall.common.enumm.PurchaseStateEnum;
import com.self.cloudmall.common.utils.R;
import com.self.cloudmall.wms.entity.PurchaseDetailEntity;
import com.self.cloudmall.wms.entity.PurchaseEntity;
import com.self.cloudmall.wms.mapper.PurchaseMapper;
import com.self.cloudmall.wms.service.PurchaseDetailService;
import com.self.cloudmall.wms.service.PurchaseService;
import com.self.cloudmall.wms.service.WareSkuService;
import com.self.cloudmall.wms.utils.PageUtils;
import com.self.cloudmall.wms.utils.Query;
import com.self.cloudmall.wms.vo.MergeVo;
import com.self.cloudmall.wms.vo.PurchaseDoneVo;
import com.self.cloudmall.wms.vo.PurchaseItemDoneVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseMapper, PurchaseEntity> implements PurchaseService {

    @Autowired
    private PurchaseDetailService purchaseDetailService;
    @Autowired
    private WareSkuService wareSkuService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<PurchaseEntity> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<PurchaseEntity> lambda = queryWrapper.lambda();
        String key = (String) params.get("key");
        if (StringUtils.isNotEmpty(key)){
            lambda.and(w -> w.eq(PurchaseEntity::getId,key).or()
                    .like(PurchaseEntity::getAssigneeName,key));
        }
        String status = (String) params.get("status");
        if (StringUtils.isNotEmpty(status)){
            lambda.eq(PurchaseEntity::getStatus,status);
        }
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public R mergePurchase(MergeVo mergeVo) {
        //采购单id如果不存在就新建一个，
        Long purchaseId = mergeVo.getPurchaseId();
        if (purchaseId == null){
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            purchaseEntity.setStatus(PurchaseStateEnum.STATENEW.getCode());
            Date date = new Date();
            purchaseEntity.setCreateTime(date);
            purchaseEntity.setUpdateTime(date);
            this.save(purchaseEntity);
            purchaseId = purchaseEntity.getId();
        }
        //需求单/采购单只有状态“创建”和“分配”才可以合并
        List<PurchaseDetailEntity> detailEntities = purchaseDetailService.listByIds(mergeVo.getItems());
        if (CollectionUtils.isEmpty(detailEntities)){
            return R.error("查询需求单不存在");
        }
        List<Integer> states = Arrays.asList(PurDetailStateEnum.STATENEW.getCode(), PurDetailStateEnum.ASSIGN.getCode());
        for (PurchaseDetailEntity detail : detailEntities){
            if (!states.contains(detail.getStatus())){
                return R.error("需求单状态存在创建和分配以外的状态");
            }
        }
        detailEntities = detailEntities.stream().filter(x -> x.getStatus() == PurDetailStateEnum.ASSIGN.getCode() 
                || x.getStatus() == PurDetailStateEnum.STATENEW.getCode()).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(detailEntities)){
            return R.error("需求单状态是创建和已分配不存在");
        }
        PurchaseEntity purchaseEntity = this.baseMapper.selectById(purchaseId);
        if (purchaseEntity == null || purchaseEntity.getStatus() == null){
            return R.error("采购单不存在");
        }else if (!states.contains(purchaseEntity.getStatus().intValue())){
           return R.error("采购单除了创建和已分配之外，不能合并需求单");
        }
        //更新需求单状态为“已分配”
        Long finalPurchaseId = purchaseId;
        detailEntities = detailEntities.stream().map(x -> {
            PurchaseDetailEntity detailEntity = new PurchaseDetailEntity();
            detailEntity.setId(x.getId());
            detailEntity.setPurchaseId(finalPurchaseId);
            detailEntity.setStatus(PurDetailStateEnum.ASSIGN.getCode());
            return detailEntity;
        }).collect(Collectors.toList());
        purchaseDetailService.updateBatchById(detailEntities);

        //更新采购单更新时间
        PurchaseEntity purchase = new PurchaseEntity();
        purchase.setId(purchaseId);
        purchase.setUpdateTime(new Date());
        this.updateById(purchase);
        return R.ok();
    }

    @Override
    public PageUtils queryPageUnreceivePurchase(Map<String, Object> params) {
        QueryWrapper<PurchaseEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(PurchaseEntity::getStatus,Arrays.asList(PurchaseStateEnum.STATENEW.getCode(),PurchaseStateEnum.ASSIGN.getCode()));
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public R received(List<Long> ids) {
        //验证采购单下有无需求单
        for (Long id : ids){
            Integer count = purchaseDetailService.lambdaQuery().eq(PurchaseDetailEntity::getPurchaseId, id).count();
            if (count == null || count == 0){
                return R.error("存在采购单下无需求单的情况，请重新选择");
            }
        }
        //过滤出已分配的采购单
        List<PurchaseEntity> purchaseEntities = this.baseMapper.selectBatchIds(ids);
        if (CollectionUtils.isEmpty(purchaseEntities)){
            return R.error("查询不到采购单");
        }
        for (PurchaseEntity pur : purchaseEntities){
            if (pur.getStatus() != null && pur.getStatus() != PurchaseStateEnum.ASSIGN.getCode()){
                return R.error("采购单状态存在不是已分配的，请重新选择");
            }
        }
        List<PurchaseEntity> collect = purchaseEntities.stream().filter(x -> x.getStatus() != null && PurchaseStateEnum.ASSIGN.getCode() == x.getStatus())
                .map(x -> {
                    PurchaseEntity purchaseEntity = new PurchaseEntity();
                    purchaseEntity.setId(x.getId());
                    purchaseEntity.setStatus(PurchaseStateEnum.RECEIVED.getCode());
                    return purchaseEntity;
                }).collect(Collectors.toList());
        //更新状态为已领取
         this.updateBatchById(collect);
        //更新需求单张状态采购中
        PurchaseDetailEntity pde = new PurchaseDetailEntity();
        pde.setStatus(PurDetailStateEnum.PURCHASING.getCode());
        purchaseDetailService.lambdaUpdate().in(PurchaseDetailEntity::getPurchaseId,ids)
        .update(pde);
        return R.ok();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public R done(PurchaseDoneVo doneVo) {
        Long id = doneVo.getId();
        //更新采购单详情为已完成，更新如果失败，记录原因，
        boolean flag = true;
        List<PurchaseDetailEntity> updates = Lists.newArrayList();
        for(PurchaseItemDoneVo item : doneVo.getItems()){
            PurchaseDetailEntity detailEntity = new PurchaseDetailEntity();
            if (item.getStatus() == null){
                return R.error("采购详情状态参数为空");
            } else if (item.getStatus() == PurDetailStateEnum.FAIL.getCode()){
                flag = false;
                detailEntity.setStatus(item.getStatus());
            }else if (item.getStatus() != PurDetailStateEnum.PURCHASING.getCode()){
                return R.error("采购详情状态必须是采购中的才能完成");
            }else{
                detailEntity.setStatus(PurDetailStateEnum.FINISH.getCode());
                //更新库存
                PurchaseDetailEntity purchaseDetail = purchaseDetailService.getById(item.getItemId());
                if (purchaseDetail == null || purchaseDetail.getStatus() == null){
                    return R.error("采购单详情不存在");
                }
                wareSkuService.addWareSku(item,purchaseDetail);
            }
            detailEntity.setId(item.getItemId());
            updates.add(detailEntity);
        }
        purchaseDetailService.updateBatchById(updates);
        //更新采购单状态已完成
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(id);
        purchaseEntity.setStatus(flag?PurchaseStateEnum.FINISH.getCode():PurchaseStateEnum.EXCEPTION.getCode());
        purchaseEntity.setUpdateTime(new Date());
        this.updateById(purchaseEntity);
        return R.ok();
    }

}